const Decimal = require('decimal.js');

function getLeftStickChange(finalPoints, leftStickNum) {
  // 一位同点的选手数量
  const topSameSize = finalPoints.filter(finalP => finalP === finalPoints[0]).length;
  let changePoints = [0, 0, 0, 0];
  // 分配剩余立直棒
  if (leftStickNum > 0) {
    // 无人同点
    if (topSameSize === 1) {
      changePoints[0] = leftStickNum * 1000;
    }
    // 两人或四人同点时
    else if (topSameSize !== 3) {
      const average = leftStickNum * 1000 / topSameSize;
      changePoints = [...new Array(topSameSize).fill(average), 0, 0, 0]
    }
    // 三人同点时，第一个人拿4/10，其余人拿3/10
    else {
      const average = (leftStickNum * 1000) / 10;
      const first = average * 4;
      const other = average * 3;
      changePoints = [first, other, other, 0]
    }
  }
  return changePoints;
}

function getChangeScores(finalPoints, orderScores) {
  let index = 0;
  let finalPoint;
  let samePointNum = 0;
  const changeScores = [];
  while (index < finalPoints.length && changeScores[index] === undefined) {
    finalPoint = finalPoints[index];
    // 判断同等人数
    samePointNum = finalPoints.slice(index).filter(point => point === finalPoint).length;
    if (samePointNum === 1) {
      changeScores[index] = orderScores[index];
    }
    // 多人同点时的处理
    else {
      // 算出待分配的总分
      const sumScore = orderScores.slice(index, index + samePointNum).reduce((sum, score) => sum + score, 0);
      // 算出平均分
      const averageScore = sumScore / samePointNum;
      // 平均分是整数，则都获取平均分
      if (Math.floor(averageScore) === averageScore) {
        changeScores.push(...(new Array(samePointNum).fill(averageScore)))
      }
      // 如果不能被整除，则顺位在前的获取余数
      else {
        const leftScore = sumScore % samePointNum;
        const floorAverage = Math.floor(averageScore);
        // 座次顺位在前的获取余数
        changeScores.push(floorAverage + leftScore);
        changeScores.push(...(new Array(samePointNum - 1).fill(floorAverage)))
      }
    }
    index = changeScores.length;
  }
  return changeScores;
}

export function getFinalScores(finalPoints, leftStickNum, orderScores) {
  const leftStickChange = getLeftStickChange(finalPoints, leftStickNum);
  const changeScores = getChangeScores(finalPoints, orderScores)
  return finalPoints.map((finalPoint, index) => {
    const result = new Decimal(finalPoint).plus(leftStickChange[index]).dividedBy(1000).minus(30).plus(changeScores[index])
    return result.toNumber();
  })
}